package com.rh.monitoring.sections.user;

import android.content.Context;

import com.yuyuto.conn.RetrofitManager;
import com.yuyuto.conn.exception.ExceptionEngine;
import com.yuyuto.conn.exception.ResultException;
import com.yuyuto.conn.interf.IUser;
import com.yuyuto.conn.model.request.BaseRequest;
import com.yuyuto.conn.model.response.HttpResult;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

public class UserPresenter implements IUser {

    private RetrofitManager mRetrofitManager;
    private static UserPresenter userPresenter;

    private UserPresenter(Context context) {
        mRetrofitManager = RetrofitManager.getInstance(context.getApplicationContext());
    }

    public static UserPresenter getInstance(Context context) {
        /* 如果第一个线程获取到了单例的实例对象，
         * 后面的线程再获取实例的时候不需要进入同步代码块中了
         * */
        if (userPresenter == null) {
            //同步代码块用的锁是单例的字节码文件对象，且只能用这个锁
            synchronized (UserPresenter.class) {
                if (userPresenter == null) {
                    userPresenter = new UserPresenter(context);
                }
            }
        }
        return userPresenter;
    }

    /**
     * 用来统一处理Http的resultCode,并将HttpResult的Data部分剥离出来返回给subscriber
     *
     * @param <T> Subscriber真正需要的数据类型，也就是Data部分的数据类型
     */
    private class HttpResultFunc<T> implements Func1<HttpResult<T>, T> {

        @Override
        public T call(HttpResult<T> httpResult) {
            if (httpResult.getCode() != 1) {
                throw new ResultException(httpResult.getCode(), httpResult.getMsg());
            }
            return httpResult.getData();
        }
    }

    private class HttpResponseFunc<T> implements Func1<Throwable, Observable<T>> {
        @Override
        public Observable<T> call(Throwable throwable) {
            //ExceptionEngine为处理异常的驱动器
            return Observable.error(ExceptionEngine.handleException(throwable));
        }
    }

    @Override
    public void login(Subscriber<Object> subscriber, String userName, String password) {
        mRetrofitManager.service.login(userName, password, 1)
                .map(new HttpResultFunc<>())
                .onErrorResumeNext(new HttpResponseFunc<>())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }

    @Override
    public void logout(Subscriber<Object> subscriber, String userName, String password) {
        mRetrofitManager.service.logout(new BaseRequest())
                .map(new HttpResultFunc<>())
                .onErrorResumeNext(new HttpResponseFunc<>())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }

    @Override
    public void modifyPwd(Subscriber<Object> subscriber, String userName, String password) {
        mRetrofitManager.service.modifyPwd(new BaseRequest())
                .map(new HttpResultFunc<>())
                .onErrorResumeNext(new HttpResponseFunc<>())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }
}
